/*
 * Copyright 2010 Mttang.com All right reserved. This software is the confidential and proprietary information of
 * Mttang.com ("Confidential Information"). You shall not disclose such Confidential Information and shall use it only
 * in accordance with the terms of the license agreement you entered into with Mttang.com.
 */
package com.mttang.info.core;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.mttang.framework.core.paginated.util.PagedFliper;
import com.mttang.framework.core.pojos.BaseDTO;
import com.mttang.framework.core.pojos.PrintableAndSerializeableDTO;

/**
 * 类ResultDTOWrapper.java的实现描述：查询结果封装
 * 
 * @author caizhan 2010-6-3 下午05:07:16
 */
public class ResultDTOWrapper {

    private Log         logger = LogFactory.getLog(getClass());

    /**
     * 查询结果集
     */
    private ResultDTO   resultDTO;
    /**
     * 分页信息
     */
    // private PageModel pageModel;
    private PagedFliper pagedFliper;

    public ResultDTOWrapper(ResultDTO resultDTO) {
        super();
        this.resultDTO = resultDTO;
    }

    /**
     * @return the pagedFliper
     */
    public PagedFliper getPagedFliper() {
        return pagedFliper;
    }

    /**
     * @param pagedFliper the pagedFliper to set
     */
    public void setPagedFliper(PagedFliper pagedFliper) {
        this.pagedFliper = pagedFliper;
    }

    /**
     * 封装成response的web参数
     * 
     * @return response的参数
     */
    public Map<Object, Object> wrap() {
        Map<Object, Object> obj = new HashMap<Object, Object>();

        List<Map<String, Object>> items = new ArrayList<Map<String, Object>>();
        Class<?> cls = resultDTO.getDtoClass();
        List<Object> dtos = resultDTO.getRecords();
        for (int i = 0, num = dtos.size(); i < num; i++) {
            items.add(new HashMap<String, Object>());
        }

        try {
            // 将dto结果集封装为List<Map>的形式
            getValue(cls, items, dtos);
        } catch (Exception e) {
            // dto 成员函数出错
            if (logger.isInfoEnabled()) {
                logger.info("---DTO 成员函数错误---", e);
            }
        }
        obj.put(ServiceRequestAnalyser.K_list, items);

        if (pagedFliper != null) {
            pagedFliper.setRecordCount(this.resultDTO.getTotalRecord().intValue());
            obj.put(ServiceRequestAnalyser.K_pageModel, pagedFliper);
        }

        return obj;
    }

    /**
     * 调用"get"函数,将dto结果集封装成List<Map>参数集
     * 
     * @param cls dto类
     * @param items map结果集
     * @param dtos dto实体
     * @throws Exception
     */
    private void getValue(Class<?> cls, List<Map<String, Object>> items, List<Object> dtos) throws Exception {
        // 递归父类，不等于BaseDTO继续递归
        if (!BaseDTO.class.equals(cls.getSuperclass())
            && !PrintableAndSerializeableDTO.class.equals(cls.getSuperclass())) {
            getValue(cls.getSuperclass(), items, dtos);
        }

        // 取得所有字段属性
        Field fieldlist[] = cls.getDeclaredFields();
        for (int i = 0; i < fieldlist.length; i++) {
            Field fld = fieldlist[i];
            int mod = fld.getModifiers();
            if (Modifier.isFinal(mod) || Modifier.isStatic(mod) || Modifier.isNative(mod)
                || Modifier.isSynchronized(mod) || Modifier.isTransient(mod)) {
                continue; // 特殊类型除外
            }
            String name = fld.getName();
            String first = name.charAt(0) + "";
            first = first.toUpperCase();
            String methodName = "get" + first + name.substring(1); // 调用get函数封装
            Method meth = cls.getMethod(methodName);
            for (int j = 0, num = dtos.size(); j < num; j++) {
                Object obj = dtos.get(j);
                items.get(j).put(name, meth.invoke(obj)); // 设置get函数的返回值
            }
        }
    }

}
